﻿using FastExecutor.Base.Util;
using FastExecutor.Message.Annotation;
using FastExecutor.Message.Base.Design;
using FastExecutor.Message.Design;
using FastUtil.Extra;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace FastExecutor.Message.Application
{
    public class MessageCenter
    {
        private static MessageCenter _MessageCenter = null;
        private static object MessageCenter_Lock = new object(); //锁同步

        public static MessageCenter GetInstance()
        {
            if (_MessageCenter == null)
            {
                lock (MessageCenter_Lock)
                {
                    if (_MessageCenter == null)
                    {
                        _MessageCenter = new MessageCenter();
                    }
                }
            }
            return _MessageCenter;
        }

        public void Init()
        {
            List<Type> HandlerTypeList = InjectUtil.Container.GetRegistType(typeof(IFastMessageHandle));
            foreach (Type HandlerType in HandlerTypeList)
            {
                MessageChanelAttribute Channel = Attribute.GetCustomAttribute(HandlerType, typeof(MessageChanelAttribute)) as MessageChanelAttribute;
                RedisUtil.Subscribe(Channel.ChannelName, ((FastDefaultMessageHandler)InjectUtil.Container.Resolve(HandlerType)).HandleMessage);
            }
        }

        public void SendMessage<T>(string ChannleName, T CustomMessageEntity,Dictionary<string,string> ExtraData = null)
        {
            FastExecutor.Message.Design.Message MessageEntity = new Design.Message();
            MessageEntity.MessageChannel = ChannleName;
            MessageHead Head = new MessageHead();
            MessageBody Body = new MessageBody();
            Body.MessageMapperType = typeof(T);
            Body.MessageJsonContent = JsonConvert.SerializeObject(CustomMessageEntity);
            MessageEntity.MessageHead = Head;
            MessageEntity.MessageBody = Body;
            if (ExtraData!=null)
            {
                foreach (var item in ExtraData)
                {
                    MessageEntity.AddExtra(item.Key, item.Value);
                }
            }
            RedisUtil.Publish(ChannleName, MessageEntity);
        }

    }
}
